package com.ruoyi.project.monitor.warndistribute.service.impl;

import java.util.Date;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.EmailUtil;
import com.ruoyi.common.utils.RedisMonitorUtil;
import com.ruoyi.common.utils.EmailUtil.MailFromUserModel;
import com.ruoyi.common.utils.EmailUtil.MailToUserModel;
import com.ruoyi.common.utils.EmailUtil.SendEmailResult;
import com.ruoyi.common.utils.text.Convert;
import com.ruoyi.project.monitor.warndistribute.domain.WarnDistribute;
import com.ruoyi.project.monitor.warndistribute.mapper.WarnDistributeMapper;
import com.ruoyi.project.monitor.warndistribute.service.IWarnDistributeService;
import com.ruoyi.project.monitor.warnmessage.domain.WarnMessage;
import com.ruoyi.project.monitor.warnmessage.service.IWarnMessageService;

/**
 * 告警分发Service业务层处理
 * 
 * @author shixiangwen
 * @date 2020-04-09
 */
@Service
public class WarnDistributeServiceImpl implements IWarnDistributeService {

	protected static Log logger = LogFactory.getLog(WarnDistributeServiceImpl.class);

	public final static String WARN_EMAIL_RECIVE = "114476513@qq.com";

	@Autowired
	WarnDistributeMapper warnDistributeMapper;

	@Autowired
	IWarnMessageService iWarnMessageService;

	public void sendEmail(String resource, String title, String content) {

		logger.info(String.format("send messgae.[%s], [%s]", title, content));

		MailFromUserModel fromUser = new MailFromUserModel("smtp.163.com", "shixiangwen03@163.com", "mnb2009");
		MailToUserModel toUser = new MailToUserModel(WARN_EMAIL_RECIVE, title, content, null, null);
		SendEmailResult result = EmailUtil.sendSMTPEmail(fromUser, toUser);

		WarnMessage warnMessage = new WarnMessage();
		warnMessage.setResource(resource);
		warnMessage.setContent(content);
		warnMessage.setTitle(title);
		warnMessage.setCreateTime(DateUtils.getNowDate());
		warnMessage.setSendTo(WARN_EMAIL_RECIVE);
		warnMessage.setResult(result.getMsg());

		iWarnMessageService.insertWarnMessage(warnMessage);
	}

	private WarnDistribute get(String resource) {
		WarnDistribute query = new WarnDistribute();
		query.setResource(resource);
		List<WarnDistribute> list = warnDistributeMapper.selectWarnDistributeList(query);
		if (!list.isEmpty()) {
			return list.get(0);
		}
		WarnDistribute warnDistribute = new WarnDistribute();
		warnDistribute.setCreateTime(DateUtils.getNowDate());
		warnDistribute.setErrorCount(0L);
		warnDistribute.setErrorSendCount(0L);
		warnDistribute.setResource(resource);
		warnDistribute.setRestoreSendCount(0L);
		warnDistribute.setSuccessCount(0L);
		warnDistribute.setError(0L);
		warnDistributeMapper.insertWarnDistribute(warnDistribute);

		return warnDistribute;
	}

	@Override
	public void onSuccess(String resource) {

		WarnDistribute warnDistribute = this.get(resource);
		if (warnDistribute.getError() == 1L) {
			long successCount = warnDistribute.getSuccessCount() + 1;
			if (successCount >= 2) {// 原来是异常的,2次正常则发送恢复消息
				sendEmail(resource, String.format("[%s][%s]已经恢复", resource, DateUtils.getTime()), String.format("[%s][%s]已经恢复,请在后台查看具体信息", resource, DateUtils.getTime()));
				warnDistribute.setError(0L);
				warnDistribute.setErrorSendCount(0L);
				warnDistribute.setSuccessCount(0L);
			} else {
				warnDistribute.setSuccessCount(successCount);
			}
		} else {
			warnDistribute.setErrorCount(0L);
		}

		warnDistributeMapper.updateWarnDistribute(warnDistribute);

	}

	@Override
	public void onError(String resource, String detail) {

		WarnDistribute warnDistribute = this.get(resource);
		warnDistribute.setErrorCount(warnDistribute.getErrorCount() + 1);

		if (warnDistribute.getErrorCount() >= 2L) {// 连续错误两次则发告警
			warnDistribute.setError(1L);
			Date lastSendTime = warnDistribute.getLastSendTime();
			if (isNeedSendEmail(warnDistribute.getErrorSendCount(), lastSendTime)) {
				warnDistribute.setLastSendTime(lastSendTime);
				sendEmail(resource, String.format("[%s][%s]出现异常,请登陆服务器查看", resource, DateUtils.getTime()), String.format("[%s][%s]出现异常,请登陆服务器查看", resource, DateUtils.getTime()));
				warnDistribute.setErrorSendCount(warnDistribute.getErrorSendCount() + 1);
				warnDistribute.setLastSendTime(DateUtils.getNowDate());
			}
		}

		warnDistributeMapper.updateWarnDistribute(warnDistribute);
	}

	private boolean isNeedSendEmail(Long errorSendCount, Date lastSendTime) {
		if (lastSendTime == null) {
			return true;
		}

		if (errorSendCount <= 0) {
			return true;
		}

		int interval = 0;
		if (errorSendCount <= 5) {// 前五次10分钟发一次
			interval = 10;
		} else if (errorSendCount <= 10) {// 5-10次 半小时发一次
			interval = 30;
		} else if (errorSendCount <= 20) {// 10-20次 一小时发一次
			interval = 60;
		} else {// 后面都是两小时发一次
			interval = 120;
		}

		if (DateUtils.addMinutes(lastSendTime, interval).before(DateUtils.getNowDate())) {
			return true;
		}

		return false;
	}

	/**
	 * 查询告警分发
	 * 
	 * @param id 告警分发ID
	 * @return 告警分发
	 */
	@Override
	public WarnDistribute selectWarnDistributeById(Long id) {
		return warnDistributeMapper.selectWarnDistributeById(id);
	}

	/**
	 * 查询告警分发列表
	 * 
	 * @param warnDistribute 告警分发
	 * @return 告警分发
	 */
	@Override
	public List<WarnDistribute> selectWarnDistributeList(WarnDistribute warnDistribute) {
		return warnDistributeMapper.selectWarnDistributeList(warnDistribute);
	}

	/**
	 * 新增告警分发
	 * 
	 * @param warnDistribute 告警分发
	 * @return 结果
	 */
	@Override
	public int insertWarnDistribute(WarnDistribute warnDistribute) {
		warnDistribute.setCreateTime(DateUtils.getNowDate());
		return warnDistributeMapper.insertWarnDistribute(warnDistribute);
	}

	/**
	 * 修改告警分发
	 * 
	 * @param warnDistribute 告警分发
	 * @return 结果
	 */
	@Override
	public int updateWarnDistribute(WarnDistribute warnDistribute) {
		warnDistribute.setUpdateTime(DateUtils.getNowDate());
		return warnDistributeMapper.updateWarnDistribute(warnDistribute);
	}

	/**
	 * 删除告警分发对象
	 * 
	 * @param ids 需要删除的数据ID
	 * @return 结果
	 */
	@Override
	public int deleteWarnDistributeByIds(String ids) {
		return warnDistributeMapper.deleteWarnDistributeByIds(Convert.toStrArray(ids));
	}

	/**
	 * 删除告警分发信息
	 * 
	 * @param id 告警分发ID
	 * @return 结果
	 */
	@Override
	public int deleteWarnDistributeById(Long id) {
		return warnDistributeMapper.deleteWarnDistributeById(id);
	}
}
